package com.followmeandroid;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.followmeandroid.enums.PrintFriend;
import com.followmeandroid.enums.ResultCode;
import com.followmeandroid.enums.ServiceUrl;
import com.followmeandroid.messages.DeleteFriendRequest;
import com.followmeandroid.models.CurrentMember;
import com.followmeandroid.models.Friend;
import com.followmeandroid.util.FollowMeSharedPreferences;
import com.followmeandroid.util.JSONHttpClient;

import java.util.ArrayList;
import java.util.List;

import static com.followmeandroid.R.layout.activity_friend_list;
/**
 * <p>Title: FriendListActivity</p>
 * <p>Description: This activity controls the content and
 * functionality of the Friends List screen.</p>
 * @team Adam Drews
 * @email adam.drews@my.uwrf.edu
 * @team Tyler Johnson
 * @email tyler.johnson@my.uwrf.edu
 * @team Nicholas Thorp
 * @email nicholas.thorp@my.uwrf.edu
 * @date 11/17/2014
 */
public class FriendListActivity extends ListActivity {

    Context thisContext;
    private EditText etSearchFriends;
    private Button btnSearchFriend;
    private ListAdapter friendListAdapter;
    private List<Friend> friends;

    /**
     * Creates the layout for the current view. It is passed a
     * bundle of data from the previous activity.
     * @param bundle        The information passed from the main activity.
     */
    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(activity_friend_list);
        thisContext = this;

        etSearchFriends = (EditText) findViewById(R.id.editFriendText);
        btnSearchFriend = (Button) findViewById(R.id.searchFriendBtn);

        btnSearchFriend.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                searchFriends(etSearchFriends.getText().toString());
            }
        });

        etSearchFriends.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                etSearchFriends.setText("");
                setUpFriendsList(CurrentMember.getMember().getFriends());
            }
        });

        setUpFriendsList(CurrentMember.getMember().getFriends());
        registerForContextMenu(this.getListView());
    }

    /**
     * Sets up the friends list view, and updates it with \
     * the given list of friends.
     * @param friendsin     The list of friends to be displayed.
     */
    private void setUpFriendsList(List<Friend> friendsin) {
        friends = friendsin;
        for(Friend fr: friends)
            System.out.println(fr.toString());
        friendListAdapter = new ArrayAdapter<Friend>(this, android.R.layout.simple_list_item_1, friends);
        setListAdapter(friendListAdapter);
    }

    /**
     * Creates the options menu.
     * @param menu      The menu to display.
     * @return true     Success!
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_friend_list, menu);
        return true;
    }

    /**
     * Controls what actions to take when an option in the options
     * menu is clicked.
     * @param item          The item that was selected.
     * @return  true        Success!
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
            case R.id.friendmenu_add_friend:
                Intent addAFriend = new Intent(FriendListActivity.this, FriendSearchActivity.class);
                startActivity(addAFriend);
                return true;
            case R.id.friendmenu_viewby_email:
                Friend.setPrint(PrintFriend.EMAIL);
                super.onContentChanged();
                return true;
            case R.id.friendmenu_viewby_name:
                Friend.setPrint(PrintFriend.NAME);
                super.onContentChanged();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    /**
     * Controls the action taken when a friend in the list is clicked.
     * @param l             The list of friends.
     * @param v             The current view.
     * @param position      The position in the list of the clicked friend.
     * @param id            ID number
     */
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Friend friend = (Friend) getListAdapter().getItem(position);
        Intent intent = new Intent(getBaseContext(), FriendProfileActivity.class);
        intent.putExtra("passedFriend", friend);
        startActivity(intent);
        //Toast.makeText(this, friend.getUserName() + " selected", Toast.LENGTH_LONG).show();
    }

    /**
     * Creates a context menu to be displayed on a long-click.
     * @param menu      The menu to display.
     * @param v         The current view.
     * @param menuInfo  Info to pass into the menu item.
     */
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
                                    ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.contextmenu_click_friend, menu);
    }

    /**
     * Controls what happens when you click on a context menu item.
     * @param item          The item clicked.
     * @return  true        Success!
     */
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        Friend friend = (Friend) getListAdapter().getItem(info.position);

        switch (item.getItemId()) {
            case R.id.friendContext_delete:
                deleteFriend(friend);

                return true;
            case R.id.friendContext_get_location:
                Toast.makeText(this, friend.getUserName() + " get location TODO", Toast.LENGTH_LONG).show();

                return true;

            case R.id.friendContext_send_message:
                Toast.makeText(this, friend.getUserName() + " send message TODO", Toast.LENGTH_LONG).show();

                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }

    /**
     * Search the currently displayed list of friends for
     * a friend that contains the input the user entered.
     * @param name          The name of the friend to be searched for.
     */
    private void searchFriends(String name) {

        List<Friend> currentfriends = CurrentMember.getMember().getListOfFriends();
        System.out.println(friends);
        List<Friend> friendSearch = new ArrayList<Friend>();
        for (Friend f : currentfriends) {
            if (f.getFirstName().toLowerCase().contains(name.toLowerCase()) || f.getLastName().toLowerCase().contains(name.toLowerCase())
                    || f.getUserName().toLowerCase().contains(name.toLowerCase())) {
                if (!friendSearch.contains(f)) {
                    friendSearch.add(f);
                }
            }
        }
        setUpFriendsList(friendSearch);
        super.onContentChanged();
    }

    /**
     * Controls what happens after this activity is resumed from inactivity.
     * It refreshes the friends list view.
     */
    @Override
    public void onResume()
    {  // After a pause OR at startup
        super.onResume();

        friends = CurrentMember.getMember().getListOfFriends();
        setUpFriendsList(friends);
        super.onContentChanged();
    }

    /**
     * This method will delete the given friend from the member's friends
     * list, and remove them from the friend list view.
     * @param friend            The friend to be removed.
     */
    protected void deleteFriend(final Friend friend) {
        DeleteFriendRequest deletefriend = new DeleteFriendRequest(friend.getFriendID().toString());

        new AsyncTask<DeleteFriendRequest, JSONHttpClient, Integer> (){

            /**
             * The operation to be performed by the thread in the background.
             * @param params        A delete friend request.
             * @return result       The result from the request.
             */
            @Override
            protected Integer doInBackground (DeleteFriendRequest...params){
                Integer result = 0;

                try {
                    // Call delete, delete friends.
                    result = JSONHttpClient.Delete(ServiceUrl.DELETE_FRIEND.toString(), params[0].toKeyValuePairs());

                } catch (Exception e) {
                    Log.d("AsyncDeleteFriend", e.getMessage());
                }
                return result;
            }

            /**
             * Displays a please wait pop up before the thread executes.
             */
            @Override
            protected void onPreExecute () {

                super.onPreExecute();
                Toast.makeText(thisContext, "Please Wait...", Toast.LENGTH_SHORT).show();
            }

            /**
             * Displays the result from trying to delete the friend. This result is determined
             * be a result code received by the server.
             * @param result        The failure or success of the action.
             */
            @Override
            protected void onPostExecute (Integer result){
                //result is http result code, 200 = OK
                if (ResultCode.get(result) == ResultCode.OK) {
                    CurrentMember.getMember().deleteFriend(friend);
                    friends.remove(friend);
                    FollowMeSharedPreferences.saveMember();
                    Toast.makeText(thisContext, friend.getUserName() + " deleted!", Toast.LENGTH_LONG).show();
                } else {
                    //make them try again!
                    Toast.makeText(thisContext, "Friend not found, or you are no longer friends!", Toast.LENGTH_LONG).show();
                }
                setUpFriendsList(CurrentMember.getMember().getFriends());
            }
        }.execute(deletefriend);
    }
}
